package com.zheng.api.server.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zheng.api.common.constant.ApiConstant;
import com.zheng.api.common.constant.ApiResult;
import com.zheng.api.common.constant.ApiResultConstant;
import com.zheng.api.server.constant.WeChatConfigure;
import com.zheng.api.server.service.base.um.Base4UmbrellaService;
import com.zheng.api.server.service.command.WechatBusiness4CommandInterface;
import com.zheng.api.server.service.mq.um.Mq4UmbrellaMachineNotify;
import com.zheng.api.server.service.mq.um.Mq4UmbrellaWechatappNotify;
import com.zheng.business.common.constant.BusinessConstant;
import com.zheng.business.dao.model.*;
import com.zheng.business.rpc.api.BusinessOrderUmbrellaConsumptionService;
import com.zheng.business.rpc.api.BusinessOrderUmbrellaDepositService;
import com.zheng.business.rpc.api.BusinessOrderUmbrellaRechargeService;
import com.zheng.business.rpc.api.BusinessOrderUmbrellaTimecardService;
import com.zheng.common.constant.Constant;
import com.zheng.common.constant.PayConstant;
import com.zheng.common.domain.Location;
import com.zheng.common.exception.BaseException;
import com.zheng.common.util.*;
import com.zheng.pay.dao.model.PayMchInfo;
import com.zheng.umbrella.common.constant.UmbrellaConstant;
import com.zheng.umbrella.dao.model.*;
import com.zheng.umbrella.rpc.api.*;
import com.zheng.upms.rpc.api.UpmsSystemParamService;
import com.zheng.wechat.mp.dao.model.WechatMpGzuser;
import com.zheng.wechat.mp.dao.model.WechatMpSystemAccount;
import com.zheng.wechat.mp.dao.model.WechatMpSystemAccountExample;
import com.zheng.wechat.mp.rpc.api.WechatMpGzuserService;
import com.zheng.wechat.mp.rpc.api.WechatMpSystemAccountService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by lvb.
 * 小程序接口服务
 */
@Service("apiServerUmbrellaService")
public class ApiServerUmbrellaService extends Base4UmbrellaService {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ApiServerUmbrellaService.class);

    @Autowired
    ApiServerPayService apiServerPayService;
    @Autowired
    WechatMpGzuserService wechatMpGzuserService;
    @Autowired
    WechatMpSystemAccountService wechatMpSystemAccountService;
    @Autowired
    UmbrellaHardwareMachineService umbrellaHardwareMachineService;
    @Autowired
    UmbrellaHardwareBatchService umbrellaHardwareBatchService;
    @Autowired
    UmbrellaHardwarePathService umbrellaHardwarePathService;
    @Autowired
    UmbrellaHardwareUmbrellaService umbrellaHardwareUmbrellaService;
    @Autowired
    UmbrellaRuleDepositService umbrellaRuleDepositService;
    @Autowired
    UmbrellaRuleRechargeService umbrellaRuleRechargeService;
    @Autowired
    UmbrellaRuleRentService umbrellaRuleRentService;
    @Autowired
    UmbrellaRuleTimecardService umbrellaRuleTimecardService;
    @Autowired
    BusinessOrderUmbrellaConsumptionService businessOrderUmbrellaConsumptionService;
    @Autowired
    BusinessOrderUmbrellaDepositService businessOrderUmbrellaDepositService;
    @Autowired
    BusinessOrderUmbrellaTimecardService businessOrderUmbrellaTimecardService;
    @Autowired
    BusinessOrderUmbrellaRechargeService businessOrderUmbrellaRechargeService;
    @Autowired
    UmbrellaHardwareManageLogService umbrellaHardwareManageLogService;
    @Autowired
    WxTemplateService wxTemplateService;
    @Autowired
    UpmsSystemParamService upmsSystemParamService;
    @Autowired
    ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    Mq4UmbrellaMachineNotify mq4UmbrellaMachineNotify;
    @Autowired
    Mq4UmbrellaWechatappNotify mq4UmbrellaWechatappNotify;
    @Autowired
    private JmsTemplate jmsQueueTemplate;

    /**
     * 支付配置
     */
    @Value("${pay.paycenter.baseUrl}")
    private String baseUrl;
    @Value("${pay.paycenter.innerPayNotifyUrl}")
    private String innerPayNotifyUrl;
    @Value("${pay.paycenter.innerRefundNotifyUrl}")
    private String innerRefundNotifyUrl;
    /**
     * 缓存模块前缀
     */
    @Value("${Redis.CacheModule}")
    private String cacheModule;
    //测试环境标识
    @Value("${pay.order.test.enable}")
    private String payOrderTestEnable;

    /**
     * 根据定位及显示获取伞机
     * @param longitude
     * @param latitude
     * @param distance
     * @param ipAddress
     * @return
     */
    public List<UmbrellaHardwareMachine> getMachineInfos(String longitude,String latitude,String distance,String ipAddress) throws Exception {
        LOGGER.info( "Start get getMachineInfos" );

//        ApiResult result = null;
//        JSONObject dataInfo = new JSONObject();
        //转换为long
        double lat = Double.parseDouble(latitude);
        double lng = Double.parseDouble(longitude);
        double dist = Double.parseDouble(distance);
//        Location[] locations = LocationUtil.getRectangle4Point(lat,
//                lng, dist);
        Double[] locations = LocationUtil.getLatAndLngRange(lat,lng,dist);
        UmbrellaHardwareMachineExample example = new UmbrellaHardwareMachineExample();
        UmbrellaHardwareMachineExample.Criteria criteria = example.createCriteria();
        criteria.andLatitudeBetween(new BigDecimal(locations[0]),new BigDecimal(locations[1]));
        criteria.andLongitudeBetween(new BigDecimal(locations[2]),new BigDecimal(locations[3]));
        //未删除
        criteria.andFlagEqualTo(Constant.CONST_FLAG_NORMAL);
        //状态在线
        //criteria.andStatusEqualTo(2);
        ArrayList<Integer> statusList = new ArrayList<Integer>();
        statusList.add(ApiConstant.UM_MACHINE_STATUS_UP);
        if("true".equals(upmsSystemParamService.querySystemParamValueByParam_key("UMBRELLA_MACHINE_SHOW_OFFLINE"))){
            statusList.add(ApiConstant.UM_MACHINE_STATUS_DOWN);
        }
        if("true".equals(upmsSystemParamService.querySystemParamValueByParam_key("UMBRELLA_MACHINE_SHOW_FAULT"))){
            statusList.add(ApiConstant.UM_MACHINE_STATUS_FAIL);
        }
        if("true".equals(upmsSystemParamService.querySystemParamValueByParam_key("UMBRELLA_MACHINE_SHOW_OFF"))){
            statusList.add(ApiConstant.UM_MACHINE_STATUS_OFF);
        }
        criteria.andStatusIn(statusList);
        return umbrellaHardwareMachineService.selectByExample(example);
//        dataInfo.put("dataInfo",JsonUtil.parseList2JSON(umbrellaHardwareMachineList));

//        result = new ApiResult(ApiResultConstant.SUCCESS.code,"获取伞机成功",dataInfo);
//        return result;
    }

    /**
     * 获取预付金规则
     * @param machineCode
     * @return
     */
    public List<UmbrellaRuleDeposit> getRuleDeposit(Integer account,String machineCode) {
        LOGGER.info( "Start getRuleDeposit" );
        Integer agentId = null;
        Integer id = null;
        if(StringUtils.isNotBlank(machineCode)){//如果存在设备码，则使用设备码获取规则
            UmbrellaHardwareMachineExample machineExample = new UmbrellaHardwareMachineExample();
            machineExample.createCriteria().andCodeEqualTo(machineCode);
            UmbrellaHardwareMachine machine = umbrellaHardwareMachineService.selectFirstByExample(machineExample);
            if(machine!=null){
                id = machine.getRuleDepositId();
            }
        }
        if(id==null){
                UmbrellaHardwareMachine machine = super.baseSelectUmbrellaHardwareMachineNoCache(machineCode);
                if(machine!=null){
                    agentId = machine.getAgentId();
                }
                if(agentId==null){
                    WechatMpGzuser gzuser = wechatMpGzuserService.selectByPrimaryKey(account);
                    agentId = gzuser.getUserAgentId();
                }
        }
        //机器编号需要特殊处理
//         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
        UmbrellaRuleDepositExample example = new UmbrellaRuleDepositExample();
        UmbrellaRuleDepositExample.Criteria criteria = example.createCriteria();
        //未删除
        criteria.andFlagEqualTo(Constant.CONST_FLAG_NORMAL);
        //状态正常
        criteria.andStatusEqualTo(Constant.CONST_ENABLE);
        long nowtime = new Date().getTime();
        criteria.andBeginTimeLessThanOrEqualTo(nowtime);
        criteria.andEndTimeGreaterThanOrEqualTo(nowtime);
        if(id!=null) {
            criteria.andIdEqualTo(id);
        }else {
            criteria.andAgentIdEqualTo(agentId);
        }
        example.setOrderByClause("price desc");
        UmbrellaRuleDeposit deposit = umbrellaRuleDepositService.selectFirstByExample(example);
        List<UmbrellaRuleDeposit>  depositList = new ArrayList<UmbrellaRuleDeposit>();
        if(deposit!=null){
            depositList.add(deposit);
        }
        return depositList;

    }

    /**
     * 获取时长卡规则
     * @param machineCode
     * @return
     */
    public List<UmbrellaRuleTimecard> getRuleTimecard(Integer account,String machineCode) {
        LOGGER.info( "Start getRuleTimecard" );

        Integer agentId = null;
        if(StringUtils.isNotBlank(machineCode)) {//如果存在设备码，则使用设备码获取规则
            UmbrellaHardwareMachine machine = super.baseSelectUmbrellaHardwareMachineNoCache(machineCode);
            if (machine != null) {
                agentId = machine.getAgentId();
            }
        }
        if(agentId == null ){
            WechatMpGzuser gzuser = wechatMpGzuserService.selectByPrimaryKey(account);
            agentId = gzuser.getUserAgentId();
        }
        if(agentId == null){
            return new ArrayList<UmbrellaRuleTimecard>();
        }

        //机器编号需要特殊处理
//         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
        UmbrellaRuleTimecardExample example = new UmbrellaRuleTimecardExample();
        UmbrellaRuleTimecardExample.Criteria criteria = example.createCriteria();
        //未删除
        criteria.andFlagEqualTo(Constant.CONST_FLAG_NORMAL);
        criteria.andAgentIdEqualTo(agentId);
        criteria.andStatusEqualTo(Constant.CONST_ENABLE);
        //有效期范围内的
//        Long second = Instant.now().getEpochSecond();
        Long time = new Date().getTime();
        criteria.andBeginTimeLessThanOrEqualTo(time);
        criteria.andEndTimeGreaterThanOrEqualTo(time);
        //按售价倒排序
        example.setOrderByClause(" cardtype asc ");
        return umbrellaRuleTimecardService.selectByExample(example);

    }

    /**
     * 购买时长卡
     * @param account
     * @param productId
     * @param ipAddress
     * @return
     */
    public ApiResult preparePayTimecard(Integer account,Integer productId,String ipAddress,String jwid) {
        LOGGER.info( "Start preparePayTimecard" );

        ApiResult result = null;
        JSONObject dataInfo = new JSONObject();

        UmbrellaRuleTimecard umbrellaRuleTimecard = super.baseSelectUmbrellaRuleTimecardNoCache(productId,true);
        if(umbrellaRuleTimecard == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"时长卡套餐不存在",null,null,dataInfo);
            return result;
        }else if((umbrellaRuleTimecard.getQuota() - umbrellaRuleTimecard.getBuycount()) <=0){
            result = new ApiResult(ApiResultConstant.FAILED.code,"时长卡已售完",null,null,dataInfo);
            return result;
        }
        //查询用户
        WechatMpGzuser wechatMpGzuser = super.baseSelectWechatMpGzuser(account,false);
        if(wechatMpGzuser == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"用户未注册",null,null,dataInfo);
            return result;
        }
        //时长卡提前购买天数限制(0或负数可随时购买，其他则可提前多少天可购买)
        int allowBeforeDate = 0;
        try {
            allowBeforeDate = Integer.parseInt(upmsSystemParamService.querySystemParamValueByParam_key("BUSINESS_ORDER_BUYTIMECARD_BEFOREDAY"));
        } catch (Exception e) {
            allowBeforeDate = 0;
        }
        //查询用户钱包
       //WechatMpSystemAccount wechatMpSystemAccount = super.baseSelectWechatMpSystemAccont(account);
       //if(wechatMpSystemAccount == null){
       //    result = new ApiResult(ApiResultConstant.FAILED.code,"用户账号数据异常",null,null,dataInfo);
       //    return result;
       //}
       //if(wechatMpSystemAccount.getCardEndtime()!=null && allowBeforeDate >0 && DateUtil.getDateIntervalOnlyDay(DateUtil.getDate(),wechatMpSystemAccount.getCardEndtime())> allowBeforeDate){
       //    result = new ApiResult(ApiResultConstant.FAILED.code,"时长卡到期["+allowBeforeDate+"]天前可购买",null,null,dataInfo);
       //    return result;
       //}
        //根据用户和代理查询用户已购买的有效时长卡
        BusinessOrderUmbrellaTimecard lastTimeCard =  super.baseSelectLastBusinessOrderUmbrellaTimecardNoCache(account,wechatMpGzuser.getUserAgentId(),false);
        if(lastTimeCard!=null) {
            if (lastTimeCard.getCardAfterEndtime() != null && allowBeforeDate > 0 && DateUtil.getDateIntervalOnlyDay(DateUtil.getDate(), lastTimeCard.getCardAfterEndtime()) > allowBeforeDate) {
                result = new ApiResult(ApiResultConstant.FAILED.code, "时长卡到期[" + allowBeforeDate + "]天前可购买", null, null, dataInfo);
                return result;
            }
        }

        if(StringUtils.isEmpty(jwid)){
            jwid = WeChatConfigure.WECHATAPP_GH;
        }
        PayMchInfo mchInfo = super.baseSelectPayMchInfoByJwid(jwid);
        if(mchInfo == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"服务器配置错误，请稍后再试",null,null,dataInfo);
            return result;
        }
        //业务流水号
        String bizSeqNo = BizSequenceUtils.getInstance().generateBizSeqNo(ModuleConstant.PAY_ORDER_BIZ_SEQUENCE_NO_PREFIX.concat(ModuleConstant.UMBRELLA_TIMECARD_BIZ_SEQUENCE_NO_PREFIX));
        //保存业务订单
        Date time = DateUtil.getNowDate();
        BusinessOrderUmbrellaTimecard businessOrderUmbrellaTimecard = new BusinessOrderUmbrellaTimecard();
        businessOrderUmbrellaTimecard.setOrderno(bizSeqNo);
        //businessOrderUmbrellaDeposit.setChannelorderno();
        //businessOrderUmbrellaDeposit.setChannelmchid();
        businessOrderUmbrellaTimecard.setMchid(mchInfo.getMchid());
        businessOrderUmbrellaTimecard.setMchorderno(bizSeqNo);
        businessOrderUmbrellaTimecard.setChannelid(PayConstant.PAY_CHANNEL_WX_JSAPI);
        businessOrderUmbrellaTimecard.setPaytype(PayConstant.PAY_METHOD_2);
        businessOrderUmbrellaTimecard.setAgentid(umbrellaRuleTimecard.getAgentId());
        businessOrderUmbrellaTimecard.setRuleid(umbrellaRuleTimecard.getId());
        businessOrderUmbrellaTimecard.setCardtype(umbrellaRuleTimecard.getCardtype());
        businessOrderUmbrellaTimecard.setUserid(account);
        businessOrderUmbrellaTimecard.setNickname(wechatMpGzuser.getNickname());
        businessOrderUmbrellaTimecard.setCreatetime(time);
        //一天后失效
        businessOrderUmbrellaTimecard.setExpiretime(DateUtil.addDate(time,1));
        //businessOrderUmbrellaDeposit.setPaysucctime();
        businessOrderUmbrellaTimecard.setUpdatetime(time);
        businessOrderUmbrellaTimecard.setAmount(umbrellaRuleTimecard.getPrice());
        businessOrderUmbrellaTimecard.setPayamount(umbrellaRuleTimecard.getSaleprice());
        BigDecimal discountedamount = umbrellaRuleTimecard.getPrice().subtract(umbrellaRuleTimecard.getSaleprice());
        businessOrderUmbrellaTimecard.setDiscountedamount(discountedamount);
        businessOrderUmbrellaTimecard.setStatus(PayConstant.PAY_STATUS_INIT & 0xFF);
        //businessOrderUmbrellaDeposit.setRefundstatus(0);
        businessOrderUmbrellaTimecard.setDescription("");

        //保存初始化订单
        int ret = businessOrderUmbrellaTimecardService.insert(businessOrderUmbrellaTimecard);
        if(ret>0) {
            //组装支付中心参数
            JSONObject paramMap = new JSONObject();
            paramMap.put("mchid", mchInfo.getMchid());                               // 商户ID
            paramMap.put("mchorderno", bizSeqNo);     // 商户订单号
            // 支付渠道ID, WX_NATIVE(微信扫码),WX_JSAPI(微信公众号或微信小程序),WX_APP(微信APP),WX_MWEB(微信H5),ALIPAY_WAP(支付宝手机支付),ALIPAY_PC(支付宝网站支付),ALIPAY_MOBILE(支付宝移动支付)
            paramMap.put("channelid", "WX_JSAPI");
            paramMap.put("amount", AmountUtil.convertDollar2Cent(String.valueOf(umbrellaRuleTimecard.getSaleprice())));                                  // 支付金额,单位分
            paramMap.put("currency", "cny");                            // 币种, cny-人民币
            paramMap.put("clientip", ipAddress);                 // 用户地址,微信H5支付时要真实的
            paramMap.put("device", "WEB");                              // 设备
            paramMap.put("subject", umbrellaRuleTimecard.getName());
            paramMap.put("body", StringUtils.isEmpty(umbrellaRuleTimecard.getDescription()) ? umbrellaRuleTimecard.getName() : umbrellaRuleTimecard.getDescription());
            paramMap.put("notifyurl", baseUrl + innerPayNotifyUrl);                       // 回调URL
            paramMap.put("param1", "");                                 // 扩展参数1
            paramMap.put("param2", "");                                 // 扩展参数2
            paramMap.put("extra", "{\"productid\":\"" + productId + "\",\"openid\":\"" + wechatMpGzuser.getOpenid() + "\"}");  // 附加参数

            //签名并向支付中心下单
            String reqSign = DigestUtil.getSign(paramMap, mchInfo.getReqkey());
            paramMap.put("sign", reqSign);                              // 签名
            String reqData = "params=" + paramMap.toJSONString();
            LOGGER.info("请求支付中心下单接口,请求数据:" + reqData);
            String url = baseUrl + "/api/v1/pay/pay/create_order?";
            String jsonResult = PayCommonUtil.call4Post(url + reqData);
            LOGGER.info("请求支付中心下单接口,响应数据:" + jsonResult);
            JSONObject retMap = JSON.parseObject(jsonResult);
            if ("SUCCESS".equals(retMap.get("retCode")) && "SUCCESS".equalsIgnoreCase(retMap.get("resCode").toString())) {
                //更新支付订单号
                BusinessOrderUmbrellaTimecardExample updateExample = new BusinessOrderUmbrellaTimecardExample();
                BusinessOrderUmbrellaTimecardExample.Criteria updateCriteria = updateExample.createCriteria();
                updateCriteria.andOrdernoEqualTo(bizSeqNo);
                BusinessOrderUmbrellaTimecard updateTimecard = new BusinessOrderUmbrellaTimecard();
                updateTimecard.setPayorderid(retMap.getString("payorderid"));
                //增加prepayid保存，用于后续小程序发送模板消息
                updateTimecard.setPrepayid(retMap.getString("prepayid"));
                businessOrderUmbrellaTimecardService.updateByExampleSelective(updateTimecard, updateExample);
                // 验签
                String checkSign = DigestUtil.getSign(retMap, mchInfo.getReskey(), "sign", "payParams");
                String retSign = (String) retMap.get("sign");
                if (checkSign.equals(retSign)) {
                    LOGGER.info("=========支付中心下单验签成功=========");
                    dataInfo.put("dataInfo", retMap);
                    result = new ApiResult(ApiResultConstant.SUCCESS.code, "生成时长卡订单成功", null, null, dataInfo);
                } else {
                    System.err.println("=========支付中心下单验签失败=========");
                    result = new ApiResult(ApiResultConstant.FAILED.code, "生成时长卡订单失败，验签失败", null, null, dataInfo);
                }
            } else {
                result = new ApiResult(ApiResultConstant.FAILED.code, "生成时长卡订单失败，支付中心响应失败", null, null, dataInfo);
            }
        }else {
            result = new ApiResult(ApiResultConstant.FAILED.code, "生成时长卡订单失败", null, null, dataInfo);
        }
        return result;
    }

    /**
     * 获取充值规则
     * @param machineCode
     * @return
     */
    public List<UmbrellaRuleRecharge> getRuleRecharge(Integer account,String machineCode) {
        LOGGER.info( "Start getRuleRecharge" );

        Integer agentId = null;
        if(StringUtils.isNotBlank(machineCode)) {//如果存在设备码，则使用设备码获取规则
            UmbrellaHardwareMachine machine = super.baseSelectUmbrellaHardwareMachineNoCache(machineCode);
            if(machine!=null){
                agentId = machine.getAgentId();
            }
        }
        if(agentId==null){
            WechatMpGzuser gzuser = wechatMpGzuserService.selectByPrimaryKey(account);
            agentId = gzuser.getUserAgentId();
        }

        //机器编号需要特殊处理
//         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
        UmbrellaRuleRechargeExample example = new UmbrellaRuleRechargeExample();
        UmbrellaRuleRechargeExample.Criteria criteria = example.createCriteria();
        //未删除
        criteria.andFlagEqualTo(Constant.CONST_FLAG_NORMAL);
        criteria.andAgentIdEqualTo(agentId);
        criteria.andStatusEqualTo(Constant.CONST_ENABLE);
        //有效期范围内的
//        Long second = Instant.now().getEpochSecond();
        Long time = new Date().getTime();
        criteria.andBeginTimeLessThanOrEqualTo(time);
        criteria.andEndTimeGreaterThanOrEqualTo(time);
//        criteria.and
        //状态正常
        criteria.andStatusEqualTo(Constant.CONST_ENABLE);
        return umbrellaRuleRechargeService.selectByExample(example);

    }

    /**
     * 获取租金规则
     * @param machineCode
     * @return
     */
    public UmbrellaRuleRent getRuleRentByMachineCode(String machineCode) throws BaseException {
        LOGGER.info( "Start getRuleRentByMachineCode" );

        //机器编号需要特殊处理
         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
        UmbrellaHardwareMachine umbrellaHardwareMachine = super.baseSelectUmbrellaHardwareMachineNoCache(machineCode);
        //判断伞机状态
        if(umbrellaHardwareMachine == null){
            throw new BaseException("该伞机尚未启用。");
        }else if(umbrellaHardwareMachine.getRentRuleId() == null ){
            throw new BaseException("伞机租金规则未设置，暂不能使用。");
        }else{
            UmbrellaRuleRent umbrellaRuleRent = super.baseSelectUmbrellaRuleRentNoCache(umbrellaHardwareMachine.getRentRuleId(),true);
            if(umbrellaRuleRent == null){
                throw new BaseException("伞机租金规则已失效。");
            }
            return umbrellaRuleRent;
        }
    }

    /**
     * 根据机器编号、account 扫码下借伞订单
     * @param params
     * @return
     */
    public ApiResult prepareUmbrellaScanBorrowInfo(String params) {
        LOGGER.info( "Start prepare prepareUmbrellaScanBorrowInfo" );
        JSONObject jsonMsg = JsonUtil.getJSONObjectFromJson(params);
        String command = jsonMsg.getString("command");
        String machineCode = jsonMsg.getString("machineCode");
        //机器编号需要特殊处理
         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
        int code = jsonMsg.getInteger("code");
        String message = jsonMsg.getString("message");
        JSONObject recvData = jsonMsg.getJSONObject("data");
        WechatBusiness4CommandInterface wechatBusiness4CommandInterface = super.baseWechatBusinessCommandFactory(machineCode);
        if(wechatBusiness4CommandInterface==null){
              return new ApiResult(ApiResultConstant.FAILED.code,ApiResultConstant.FAILED.message,ApiConstant.UMBRELLA_WECHATAPP_COMMAND_30101,machineCode,null);
        }
        ApiResult result = wechatBusiness4CommandInterface.doCommand40101("40101", machineCode, 1, "扫码借伞", recvData, false);
        return result;
    }

    /**
     * 根据机器编号、account 扫码预约还伞
     * @param params
     * @return
     */
    public ApiResult prepareUmbrellaScanReturnInfo(String params) {
        LOGGER.info( "Start prepare prepareUmbrellaScanReturnInfo" );
        JSONObject jsonMsg = JsonUtil.getJSONObjectFromJson(params);
        String command = jsonMsg.getString("command");
        String machineCode = jsonMsg.getString("machineCode");
        //机器编号需要特殊处理
         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
        int code = jsonMsg.getInteger("code");
        String message = jsonMsg.getString("message");
        JSONObject recvData = jsonMsg.getJSONObject("data");
        WechatBusiness4CommandInterface wechatBusiness4CommandInterface = super.baseWechatBusinessCommandFactory(machineCode);
        ApiResult result = wechatBusiness4CommandInterface.doCommand40201("40201", machineCode, 1, "扫码还伞", recvData, false);
        return result;
    }

    /**
     * 开始进伞
     * @param params
     * @return
     */
    public ApiResult manageUmbrellaIn(String params) {
        LOGGER.info( "Start manageUmbrellaIn" );
        JSONObject jsonMsg = JsonUtil.getJSONObjectFromJson(params);
        String command = jsonMsg.getString("command");
        String machineCode = jsonMsg.getString("machineCode");
        //机器编号需要特殊处理
         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
//        int code = jsonMsg.getInteger("code");
//        String message = jsonMsg.getString("message");
        JSONObject recvData = jsonMsg.getJSONObject("data");
        WechatBusiness4CommandInterface wechatBusiness4CommandInterface = super.baseWechatBusinessCommandFactory(machineCode);
        ApiResult result = wechatBusiness4CommandInterface.doCommand40601("40601", machineCode, 1, "开始进伞", recvData, false);
        return result;
    }
    /**
     * 结束进伞
     * @param params
     * @return
     */
    public ApiResult manageUmbrellaEndIn(String params) {
        LOGGER.info( "Start manageUmbrellaEndIn" );
        JSONObject jsonMsg = JsonUtil.getJSONObjectFromJson(params);
        String command = jsonMsg.getString("command");
        String machineCode = jsonMsg.getString("machineCode");
        //机器编号需要特殊处理
         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
//        int code = jsonMsg.getInteger("code");
//        String message = jsonMsg.getString("message");
        JSONObject recvData = jsonMsg.getJSONObject("data");
        WechatBusiness4CommandInterface wechatBusiness4CommandInterface = super.baseWechatBusinessCommandFactory(machineCode);
        ApiResult result = wechatBusiness4CommandInterface.doCommand40602("40602", machineCode, 1, "结束进伞", recvData, false);
        return result;
    }
    /**
     * 开始出伞
     * @param params
     * @return
     */
    public ApiResult manageUmbrellaOut(String params) {
        LOGGER.info( "Start manageUmbrellaOut" );
        JSONObject jsonMsg = JsonUtil.getJSONObjectFromJson(params);
        String command = jsonMsg.getString("command");
        String machineCode = jsonMsg.getString("machineCode");
        //机器编号需要特殊处理
         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
//        int code = jsonMsg.getInteger("code");
//        String message = jsonMsg.getString("message");
        JSONObject recvData = jsonMsg.getJSONObject("data");
        WechatBusiness4CommandInterface wechatBusiness4CommandInterface = super.baseWechatBusinessCommandFactory(machineCode);
        ApiResult result = wechatBusiness4CommandInterface.doCommand40701("40701", machineCode, 1, "开始出伞", recvData, false);
        return result;
    }
    /**
     * 结束出伞
     * @param params
     * @return
     */
    public ApiResult manageUmbrellaEndOut(String params) {
        LOGGER.info( "Start manageUmbrellaEndOut" );
        JSONObject jsonMsg = JsonUtil.getJSONObjectFromJson(params);
        String command = jsonMsg.getString("command");
        String machineCode = jsonMsg.getString("machineCode");
        //机器编号需要特殊处理
         machineCode = machineCode==null?"":machineCode.substring(machineCode.lastIndexOf("/")+1);if("null".equals(machineCode)){machineCode = "";}
//        int code = jsonMsg.getInteger("code");
//        String message = jsonMsg.getString("message");
        JSONObject recvData = jsonMsg.getJSONObject("data");
        WechatBusiness4CommandInterface wechatBusiness4CommandInterface = super.baseWechatBusinessCommandFactory(machineCode);
        ApiResult result = wechatBusiness4CommandInterface.doCommand40702("40702", machineCode, 1, "结束出伞", recvData, false);
        return result;
    }

    /**
     * 充值
     * @param account
     * @param productId
     * @param ipAddress
     * @return
     */
    public ApiResult prepareRecharge(Integer account,Integer productId,String ipAddress,String jwid) {
        LOGGER.info( "Start prepareRecharge" );
        ApiResult result = null;
        JSONObject dataInfo = new JSONObject();

        UmbrellaRuleRecharge umbrellaRuleRecharge = umbrellaRuleRechargeService.selectByPrimaryKey(productId);
        if(umbrellaRuleRecharge == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"生成充值订单失败,充值套餐不存在",null,null,dataInfo);
            return result;
        }

        //查询用户
        WechatMpGzuser wechatMpGzuser = super.baseSelectWechatMpGzuser(account,true);
        if(wechatMpGzuser == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"生成充值订单失败,用户未注册",null,null,dataInfo);
            return result;
        }
        //查询用户钱包
        WechatMpSystemAccount wechatMpSystemAccount = super.baseSelectWechatMpSystemAccont(account);
        if(wechatMpSystemAccount == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"生成充值订单失败,用户账号数据异常",null,null,dataInfo);
            return result;
        }

        if(StringUtils.isEmpty(jwid)){
            jwid = WeChatConfigure.WECHATAPP_GH;
        }
        PayMchInfo mchInfo = super.baseSelectPayMchInfoByJwid(jwid);
        if(mchInfo == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"服务器配置错误，请稍后再试",null,null,dataInfo);
            return result;
        }

        //业务流水号
        String bizSeqNo = BizSequenceUtils.getInstance().generateBizSeqNo(ModuleConstant.PAY_ORDER_BIZ_SEQUENCE_NO_PREFIX.concat(ModuleConstant.UMBRELLA_RECHARGE_BIZ_SEQUENCE_NO_PREFIX));
        //保存业务订单
        Date time = DateUtil.getNowDate();
        BusinessOrderUmbrellaRecharge businessOrderUmbrellaRecharge = new BusinessOrderUmbrellaRecharge();
        businessOrderUmbrellaRecharge.setOrderno(bizSeqNo);
        //businessOrderUmbrellaRecharge.setChannelorderno();
        //businessOrderUmbrellaRecharge.setChannelmchid();
        businessOrderUmbrellaRecharge.setMchid(mchInfo.getMchid());
        businessOrderUmbrellaRecharge.setMchorderno(bizSeqNo);
        businessOrderUmbrellaRecharge.setChannelid(PayConstant.PAY_CHANNEL_WX_JSAPI);
        businessOrderUmbrellaRecharge.setPaytype(PayConstant.PAY_METHOD_2);
        businessOrderUmbrellaRecharge.setAgentid(umbrellaRuleRecharge.getAgentId());
        businessOrderUmbrellaRecharge.setRuleid(umbrellaRuleRecharge.getId());
        businessOrderUmbrellaRecharge.setUserid(account);
        businessOrderUmbrellaRecharge.setNickname(wechatMpGzuser.getNickname());
        //businessOrderUmbrellaRecharge.setPaytype();
        businessOrderUmbrellaRecharge.setCreatetime(time);
        //一天后失效
        businessOrderUmbrellaRecharge.setExpiretime(DateUtil.addDate(time,1));
        //businessOrderUmbrellaRecharge.setPaysucctime();
        businessOrderUmbrellaRecharge.setUpdatetime(time);
        businessOrderUmbrellaRecharge.setPrepaidbalance(wechatMpSystemAccount.getAmount());
        businessOrderUmbrellaRecharge.setAmount(umbrellaRuleRecharge.getPrice());
        businessOrderUmbrellaRecharge.setPayamount(umbrellaRuleRecharge.getSaleprice());
        BigDecimal discountedamount = umbrellaRuleRecharge.getPrice().subtract(umbrellaRuleRecharge.getSaleprice());
        businessOrderUmbrellaRecharge.setDiscountedamount(discountedamount);
        businessOrderUmbrellaRecharge.setStatus(PayConstant.PAY_STATUS_INIT & 0xFF);
        businessOrderUmbrellaRecharge.setDescription("");
        //保存初始化订单
        int ret = businessOrderUmbrellaRechargeService.insert(businessOrderUmbrellaRecharge);

        if(ret>0) {
            //组装支付中心参数
            JSONObject paramMap = new JSONObject();
            paramMap.put("mchid",mchInfo.getMchid() );                               // 商户ID
            paramMap.put("mchorderno", bizSeqNo);     // 商户订单号
            // 支付渠道ID, WX_NATIVE(微信扫码),WX_JSAPI(微信公众号或微信小程序),WX_APP(微信APP),WX_MWEB(微信H5),ALIPAY_WAP(支付宝手机支付),ALIPAY_PC(支付宝网站支付),ALIPAY_MOBILE(支付宝移动支付)
            paramMap.put("channelid", "WX_JSAPI");
            paramMap.put("amount",AmountUtil.convertDollar2Cent(String.valueOf(umbrellaRuleRecharge.getSaleprice())));                                  // 支付金额,单位分
            paramMap.put("currency", "cny");                            // 币种, cny-人民币
            paramMap.put("clientip", ipAddress);                 // 用户地址,微信H5支付时要真实的
            paramMap.put("device", "WEB");                              // 设备
            paramMap.put("subject", umbrellaRuleRecharge.getName());
            paramMap.put("body", StringUtils.isEmpty(umbrellaRuleRecharge.getDescription())?umbrellaRuleRecharge.getName():umbrellaRuleRecharge.getDescription());
            paramMap.put("notifyurl", baseUrl + innerPayNotifyUrl);                       // 回调URL
            paramMap.put("param1", "");                                 // 扩展参数1
            paramMap.put("param2", "");                                 // 扩展参数2
            paramMap.put("extra","{\"productid\":\"" + productId + "\",\"openid\":\"" + wechatMpGzuser.getOpenid() + "\"}");  // 附加参数

            //签名并向支付中心下单
            String reqSign = DigestUtil.getSign(paramMap, mchInfo.getReqkey());
            paramMap.put("sign", reqSign);                              // 签名
            String reqData = "params=" + paramMap.toJSONString();
            LOGGER.info("请求支付中心下单接口,请求数据:" + reqData);
            String url = baseUrl + "/api/v1/pay/pay/create_order?";
            String jsonResult = PayCommonUtil.call4Post(url + reqData);
            LOGGER.info("请求支付中心下单接口,响应数据:" + jsonResult);
            JSONObject retMap = JSON.parseObject(jsonResult);
            if("SUCCESS".equals(retMap.get("retCode")) && "SUCCESS".equalsIgnoreCase(retMap.get("resCode").toString())) {
                //更新支付订单号
                BusinessOrderUmbrellaRechargeExample updateExample = new BusinessOrderUmbrellaRechargeExample();
                BusinessOrderUmbrellaRechargeExample.Criteria updateCriteria=updateExample.createCriteria();
                updateCriteria.andOrdernoEqualTo(bizSeqNo);
                BusinessOrderUmbrellaRecharge updateRecharge = new BusinessOrderUmbrellaRecharge();
                updateRecharge.setPayorderid(retMap.getString("payorderid"));
                //增加prepayid保存，用于后续小程序发送模板消息
                updateRecharge.setPrepayid(retMap.getString("prepayid"));
                businessOrderUmbrellaRechargeService.updateByExampleSelective(updateRecharge,updateExample);
                // 验签
                String checkSign = DigestUtil.getSign(retMap, mchInfo.getReskey(), "sign", "payParams");
                String retSign = (String) retMap.get("sign");
                if(checkSign.equals(retSign)) {
                    LOGGER.info("=========支付中心下单验签成功=========");
                    dataInfo.put("dataInfo", retMap);
                    result = new ApiResult(ApiResultConstant.SUCCESS.code,"生成充值订单成功",null,null,dataInfo);
                }else {
                    System.err.println("=========支付中心下单验签失败=========");
                    result = new ApiResult(ApiResultConstant.FAILED.code,"生成充值订单失败，验签失败",null,null,dataInfo);
                }
            }else{
                result = new ApiResult(ApiResultConstant.FAILED.code,"生成充值订单失败，支付中心响应失败",null,null,dataInfo);
            }

        }else {
            result = new ApiResult(ApiResultConstant.FAILED.code, "生成充值订单失败", null, null, dataInfo);
        }
        return result;
    }

    /**
     * 缴纳预付金
     * @param account
     * @param productId
     * @param ipAddress
     * @return
     */
    public ApiResult preparePayDeposit(Integer account,Integer productId,String ipAddress,String jwid) {
        LOGGER.info( "Start preparePayDeposit" );

        ApiResult result = null;
        JSONObject dataInfo = new JSONObject();

        UmbrellaRuleDeposit umbrellaRuleDeposit = super.baseSelectUmbrellaRuleDepositNoCache(productId,true);
        if(umbrellaRuleDeposit == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"生成预付金订单失败,预付金套餐不存在",null,null,dataInfo);
            return result;
        }
        //查询用户
        WechatMpGzuser wechatMpGzuser = super.baseSelectWechatMpGzuser(account,false);
        if(wechatMpGzuser == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"生成预付金订单失败,用户未注册",null,null,dataInfo);
            return result;
        }
        //查询用户钱包
        WechatMpSystemAccount wechatMpSystemAccount = super.baseSelectWechatMpSystemAccont(account);
        if(wechatMpSystemAccount == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"生成预付金订单失败,用户账号数据异常",null,null,dataInfo);
            return result;
        }
        if(wechatMpSystemAccount.getDeposit().floatValue()>0){
            result = new ApiResult(ApiResultConstant.FAILED.code,"生成预付金订单失败,用户账号已充值预付金",null,null,dataInfo);
            return result;
        }
        if(StringUtils.isEmpty(jwid)){
            jwid = WeChatConfigure.WECHATAPP_GH;
        }
        PayMchInfo mchInfo = super.baseSelectPayMchInfoByJwid(jwid);
        if(mchInfo == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"服务器配置错误，请稍后再试",null,null,dataInfo);
            return result;
        }

        //业务流水号
        String bizSeqNo = BizSequenceUtils.getInstance().generateBizSeqNo(ModuleConstant.PAY_ORDER_BIZ_SEQUENCE_NO_PREFIX.concat(ModuleConstant.UMBRELLA_DEPOSIT_BIZ_SEQUENCE_NO_PREFIX));
        //保存业务订单
        Date time = DateUtil.getNowDate();
        BusinessOrderUmbrellaDeposit businessOrderUmbrellaDeposit = new BusinessOrderUmbrellaDeposit();
        businessOrderUmbrellaDeposit.setOrderno(bizSeqNo);
        //businessOrderUmbrellaDeposit.setChannelorderno();
        //businessOrderUmbrellaDeposit.setChannelmchid();
        businessOrderUmbrellaDeposit.setMchid(mchInfo.getMchid());
        businessOrderUmbrellaDeposit.setMchorderno(bizSeqNo);
        businessOrderUmbrellaDeposit.setChannelid(PayConstant.PAY_CHANNEL_WX_JSAPI);
        businessOrderUmbrellaDeposit.setPaytype(PayConstant.PAY_METHOD_2);
        businessOrderUmbrellaDeposit.setAgentid(umbrellaRuleDeposit.getAgentId());
        businessOrderUmbrellaDeposit.setRuleid(umbrellaRuleDeposit.getId());
        businessOrderUmbrellaDeposit.setUserid(account);
        businessOrderUmbrellaDeposit.setNickname(wechatMpGzuser.getNickname());
        //businessOrderUmbrellaDeposit.setPaytype();
        businessOrderUmbrellaDeposit.setCreatetime(time);
        //一天后失效
        businessOrderUmbrellaDeposit.setExpiretime(DateUtil.addDate(time,1));
        //businessOrderUmbrellaDeposit.setPaysucctime();
        businessOrderUmbrellaDeposit.setUpdatetime(time);
        businessOrderUmbrellaDeposit.setPayamount(umbrellaRuleDeposit.getPrice());
        BigDecimal discountedamount = umbrellaRuleDeposit.getPrice().subtract(umbrellaRuleDeposit.getPrice());
        businessOrderUmbrellaDeposit.setDiscountedamount(discountedamount);
        businessOrderUmbrellaDeposit.setStatus(PayConstant.PAY_STATUS_INIT & 0xFF);
        //businessOrderUmbrellaDeposit.setRefundstatus(0);
        businessOrderUmbrellaDeposit.setDescription("");
        //保存初始化订单
        int ret = businessOrderUmbrellaDepositService.insert(businessOrderUmbrellaDeposit);
        if(ret>0) {
            //组装支付中心参数
            JSONObject paramMap = new JSONObject();
            paramMap.put("mchid", mchInfo.getMchid());                               // 商户ID
            paramMap.put("mchorderno", bizSeqNo);     // 商户订单号
            // 支付渠道ID, WX_NATIVE(微信扫码),WX_JSAPI(微信公众号或微信小程序),WX_APP(微信APP),WX_MWEB(微信H5),ALIPAY_WAP(支付宝手机支付),ALIPAY_PC(支付宝网站支付),ALIPAY_MOBILE(支付宝移动支付)
            paramMap.put("channelid", "WX_JSAPI");
            paramMap.put("amount", AmountUtil.convertDollar2Cent(String.valueOf(umbrellaRuleDeposit.getPrice())));                                  // 支付金额,单位分
            paramMap.put("currency", "cny");                            // 币种, cny-人民币
            paramMap.put("clientip", ipAddress);                 // 用户地址,微信H5支付时要真实的
            paramMap.put("device", "WEB");                              // 设备
            paramMap.put("subject", umbrellaRuleDeposit.getName());
            paramMap.put("body", StringUtils.isEmpty(umbrellaRuleDeposit.getDescription()) ? umbrellaRuleDeposit.getName() : umbrellaRuleDeposit.getDescription());
            paramMap.put("notifyurl", baseUrl + innerPayNotifyUrl);                       // 回调URL
            paramMap.put("param1", "");                                 // 扩展参数1
            paramMap.put("param2", "");                                 // 扩展参数2
            paramMap.put("extra", "{\"productid\":\"" + productId + "\",\"openid\":\"" + wechatMpGzuser.getOpenid() + "\"}");  // 附加参数

            //签名并向支付中心下单
            String reqSign = DigestUtil.getSign(paramMap, mchInfo.getReqkey());
            paramMap.put("sign", reqSign);                              // 签名
            String reqData = "params=" + paramMap.toJSONString();
            LOGGER.info("请求支付中心下单接口,请求数据:" + reqData);
            String url = baseUrl + "/api/v1/pay/pay/create_order?";
            String jsonResult = PayCommonUtil.call4Post(url + reqData);
            LOGGER.info("请求支付中心下单接口,响应数据:" + jsonResult);
            JSONObject retMap = JSON.parseObject(jsonResult);
            if ("SUCCESS".equals(retMap.get("retCode")) && "SUCCESS".equalsIgnoreCase(retMap.get("resCode").toString())) {
                //更新支付订单号
                BusinessOrderUmbrellaDepositExample updateExample = new BusinessOrderUmbrellaDepositExample();
                BusinessOrderUmbrellaDepositExample.Criteria updateCriteria = updateExample.createCriteria();
                updateCriteria.andOrdernoEqualTo(bizSeqNo);
                BusinessOrderUmbrellaDeposit updateDeposit = new BusinessOrderUmbrellaDeposit();
                updateDeposit.setPayorderid(retMap.getString("payorderid"));
                //增加prepayid保存，用于后续小程序发送模板消息
                updateDeposit.setPrepayid(retMap.getString("prepayid"));
                businessOrderUmbrellaDepositService.updateByExampleSelective(updateDeposit, updateExample);
                // 验签
                String checkSign = DigestUtil.getSign(retMap, mchInfo.getReskey(), "sign", "payParams");
                String retSign = (String) retMap.get("sign");
                if (checkSign.equals(retSign)) {
                    LOGGER.info("=========支付中心下单验签成功=========");
                    dataInfo.put("dataInfo", retMap);
                    result = new ApiResult(ApiResultConstant.SUCCESS.code, "生成预付金订单成功", null, null, dataInfo);
                } else {
                    System.err.println("=========支付中心下单验签失败=========");
                    result = new ApiResult(ApiResultConstant.FAILED.code, "生成预付金订单失败，验签失败", null, null, dataInfo);
                }
            } else {
                result = new ApiResult(ApiResultConstant.FAILED.code, "生成预付金订单失败，支付中心响应失败", null, null, dataInfo);
            }
        }else {
            result = new ApiResult(ApiResultConstant.FAILED.code, "生成预付金订单失败", null, null, dataInfo);
        }
        return result;
    }

    /**
     * 退还预付金
     * @param account
     * @param ipAddress
     * @param isForce
     * @return
     */
    public ApiResult prepareReturnDeposit(Integer account, String ipAddress, boolean isForce) {
        LOGGER.info( "Start prepareReturnDeposit" );
        ApiResult result = null;
        JSONObject dataInfo = new JSONObject();
        //查询用户
        WechatMpGzuser wechatMpGzuser = super.baseSelectWechatMpGzuser(account,false);
        if(wechatMpGzuser == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"退还预付金失败,用户未注册",null,null,dataInfo);
            return result;
        }
        //查询用户钱包
        WechatMpSystemAccount wechatMpSystemAccount = super.baseSelectWechatMpSystemAccont(account);
        if(wechatMpSystemAccount == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"退还预付金失败,用户账号数据异常",null,null,dataInfo);
            return result;
        }else if(wechatMpSystemAccount.getDeposit().floatValue()<=0){
            result = new ApiResult(ApiResultConstant.FAILED.code,"退还预付金失败,用户尚未缴纳预付金",null,null,dataInfo);
            return result;
        }else if(wechatMpSystemAccount.getUmbrellanumber().floatValue()>0 && isForce==false ){
            result = new ApiResult(ApiResultConstant.FAILED.code,"退还预付金失败,用户存在尚未归还雨伞",null,null,dataInfo);
            return result;
        }else if(wechatMpSystemAccount.getAmount().floatValue()<0 && isForce==false ){
            result = new ApiResult(ApiResultConstant.FAILED.code,"退还预付金失败,用户消費订单尚未结算完成",null,null,dataInfo);
            return result;
        }
        //查询预付金订单
        BusinessOrderUmbrellaDepositExample depositExample = new BusinessOrderUmbrellaDepositExample();
        BusinessOrderUmbrellaDepositExample.Criteria depositCriteria = depositExample.createCriteria();
        BusinessOrderUmbrellaDeposit businessOrderUmbrellaDeposit = null;
        if (!isForce) {
            depositCriteria.andUseridEqualTo(account);
            //业务处理完成
            depositCriteria.andStatusEqualTo(3);
            //未退款（状态为空）
            depositCriteria.andRefundstatusIsNull();

            businessOrderUmbrellaDeposit = businessOrderUmbrellaDepositService.selectFirstByExample(depositExample);

            if (businessOrderUmbrellaDeposit == null )
            {
                result = new ApiResult(ApiResultConstant.FAILED.code, "退还预付金失败,暂没有可退款订单", null, null, dataInfo);
                return result;
            }
        }else {
            depositCriteria.andUseridEqualTo(account);
            //业务处理完成
            depositCriteria.andStatusEqualTo(3);
            //退款状态为非订单生成
            List<Integer> values = new ArrayList<Integer>();
            values.add(2);
            values.add(4);
            depositCriteria.andRefundstatusNotIn(values);

            businessOrderUmbrellaDeposit = businessOrderUmbrellaDepositService.selectFirstByExample(depositExample);

            if (businessOrderUmbrellaDeposit == null )
            {
                result = new ApiResult(ApiResultConstant.FAILED.code, "退还预付金失败,暂没有可退款订单", null, null, dataInfo);
                return result;
            }

        }


        PayMchInfo mchInfo = super.baseSelectPayMchInfoByMchId(businessOrderUmbrellaDeposit.getMchid());
        if(mchInfo == null){
            result = new ApiResult(ApiResultConstant.FAILED.code,"服务器配置错误，请稍后再试",null,null,dataInfo);
            return result;
        }
        //业务流水号
        //String bizSeqNo = BizSequenceUtils.getInstance().generateBizSeqNo(ModuleConstant.PAY_REFUND_BIZ_SEQUENCE_NO_PREFIX.concat(ModuleConstant.UMBRELLA_DEPOSIT_BIZ_SEQUENCE_NO_PREFIX));
        //退款更新条件
        BusinessOrderUmbrellaDepositExample refundDepositExample = new BusinessOrderUmbrellaDepositExample();
        BusinessOrderUmbrellaDepositExample.Criteria  refundDepositCriteria = refundDepositExample.createCriteria();
        refundDepositCriteria.andPayorderidEqualTo(businessOrderUmbrellaDeposit.getPayorderid());
        //退款更新字段
        BusinessOrderUmbrellaDeposit refundDeposit= new BusinessOrderUmbrellaDeposit();
        //refundDeposit.setRefundamount(businessOrderUmbrellaDeposit.getPayamount());
        refundDeposit.setRefundamount(wechatMpSystemAccount.getDeposit());
        refundDeposit.setRefunddescription("退还预付金");
        refundDeposit.setRefundstatus(0);

        int ret = businessOrderUmbrellaDepositService.updateByExampleSelective(refundDeposit,refundDepositExample);
        if(ret==1) {
            //组装支付中心参数
            JSONObject paramMap = new JSONObject();
            paramMap.put("mchid", businessOrderUmbrellaDeposit.getMchid());                               // 商户ID
            paramMap.put("mchrefundno", businessOrderUmbrellaDeposit.getOrderno());     // 商户订单号
            // 支付渠道ID, WX_NATIVE(微信扫码),WX_JSAPI(微信公众号或微信小程序),WX_APP(微信APP),WX_MWEB(微信H5),ALIPAY_WAP(支付宝手机支付),ALIPAY_PC(支付宝网站支付),ALIPAY_MOBILE(支付宝移动支付)
            paramMap.put("channelid", "WX_JSAPI");
//            paramMap.put("amount", AmountUtil.convertDollar2Cent(businessOrderUmbrellaDeposit.getPayamount().toString()));  // 退款金额
            paramMap.put("amount", AmountUtil.convertDollar2Cent(wechatMpSystemAccount.getDeposit().toString()));  // 退款金额
            paramMap.put("currency", "cny");                            // 币种, cny-人民币
            paramMap.put("clientip", ipAddress);                 // 用户地址,微信H5支付时要真实的
            paramMap.put("device", "WEB");                              // 设备
            paramMap.put("subject", "退还预付金");
            paramMap.put("body", "退还预付金");
            paramMap.put("notifyurl", baseUrl + innerRefundNotifyUrl);                       // 回调URL
            paramMap.put("param1", "");                                 // 扩展参数1
            paramMap.put("param2", "");                                 // 扩展参数2
            paramMap.put("channeluser", "内部");
            paramMap.put("payorderid", businessOrderUmbrellaDeposit.getPayorderid());

            //签名并向支付中心下单
            String reqSign = DigestUtil.getSign(paramMap, mchInfo.getReqkey());
            paramMap.put("sign", reqSign);                              // 签名
            String reqData = "params=" + paramMap.toJSONString();
            LOGGER.info("请求支付中心退款接口,请求数据:" + reqData);
            String url = baseUrl + "/api/v1/pay/refund/create_order?";
            String jsonResult = PayCommonUtil.call4Post(url + reqData);
            LOGGER.info("请求支付中心退款接口,响应数据:" + result);
            JSONObject retMap = JSON.parseObject(jsonResult);
            if ("SUCCESS".equals(retMap.get("retCode")) && "SUCCESS".equalsIgnoreCase(retMap.get("resCode").toString())) {
                // 验签
                String checkSign = DigestUtil.getSign(retMap, mchInfo.getReskey(), "sign", "payParams");
                String retSign = (String) retMap.get("sign");
                if (checkSign.equals(retSign)) {
                    LOGGER.info("=========支付中心下单验签成功=========");
                    dataInfo.put("dataInfo", retMap);
                    result = new ApiResult(ApiResultConstant.SUCCESS.code, "预付金退款申请成功",null,null, dataInfo);
                } else {
                    System.err.println("=========支付中心下单验签失败=========");
                    result = new ApiResult(ApiResultConstant.FAILED.code, "预付金退款申请失败，验签失败",null,null, dataInfo);
                }
            } else {
                result = new ApiResult(ApiResultConstant.FAILED.code, "预付金退款申请失败，支付中心响应失败",null,null, dataInfo);
            }
        }else{
            result = new ApiResult(ApiResultConstant.FAILED.code, "预付金退款申请失败，更新业务订单失败",null,null, dataInfo);
        }

        return result;
    }

    /**
     * 查询充值记录
     * @param account
     * @param page
     * @return
     */
    public List<BusinessOrderUmbrellaRecharge> queryRechargeList(Integer account,Integer page) throws Exception {
        LOGGER.info( "Start queryRechargeList" );
        int rows = 10;
        int tmpPage = StringUtil.getInt(page, 1);
        BusinessOrderUmbrellaRechargeExample example = new BusinessOrderUmbrellaRechargeExample();
        BusinessOrderUmbrellaRechargeExample.Criteria criteria = example.createCriteria();
        criteria.andUseridEqualTo(account);
        criteria.andStatusBetween(2,3);// 只展示支付成功、業務處理成功的订单
        example.setOrderByClause("CreateTime desc");
        Integer total = businessOrderUmbrellaRechargeService.countByExample(example);
        Integer offset = (tmpPage - 1) * rows;
        if(offset>total)return new ArrayList<BusinessOrderUmbrellaRecharge>();
        return businessOrderUmbrellaRechargeService.selectByExampleForOffsetPage(example, (tmpPage - 1) * rows, rows);
    }
    /**
     * 查询预付金记录
     * @param account
     * @param page
     * @return
     */
    public List<BusinessOrderUmbrellaDeposit> queryDepositList(Integer account,Integer page) throws Exception {
        LOGGER.info( "Start queryDepositList" );
        int rows = 10;
        int tmpPage = StringUtil.getInt(page, 1);
        BusinessOrderUmbrellaDepositExample example = new BusinessOrderUmbrellaDepositExample();
        BusinessOrderUmbrellaDepositExample.Criteria criteria = example.createCriteria();
        criteria.andUseridEqualTo(account);
        criteria.andStatusBetween(2,3);//  只展示支付成功、業務處理成功的数据
        example.setOrderByClause("CreateTime desc");
        Integer total = businessOrderUmbrellaDepositService.countByExample(example);
        Integer offset = (tmpPage - 1) * rows;
        if(offset>total)return new ArrayList<BusinessOrderUmbrellaDeposit>();
        return businessOrderUmbrellaDepositService.selectByExampleForOffsetPage(example, (tmpPage - 1) * rows, rows);
    }

    /**
     * 查询我时长卡记录
     * @param account
     * @return
     */
    public List<BusinessOrderUmbrellaTimecard> queryMyTimecardList(Integer account,String machineCode) throws Exception {
        Integer agentId = null;
        UmbrellaHardwareMachine machine = super.baseSelectUmbrellaHardwareMachineNoCache(machineCode);
        if(machine!=null){
            agentId = machine.getAgentId();
        }
        if(agentId == null ){
            //查询用户账号
            WechatMpGzuser wechatMpGzuser = super.baseSelectWechatMpGzuser(account,false);
            agentId = wechatMpGzuser.getUserAgentId();
        }
        if(agentId == null ){
            return new ArrayList<BusinessOrderUmbrellaTimecard>();
        }

        boolean isDifference = false;
        try{
            isDifference = "true".equals(upmsSystemParamService.querySystemParamValueByParam_key("BUSINESS_ORDER_TIMECARD_SETTLE_DIFF_AGENT"));
        }catch(Exception e){}
        BusinessOrderUmbrellaTimecardExample example = new BusinessOrderUmbrellaTimecardExample();
        BusinessOrderUmbrellaTimecardExample.Criteria criteria = example.createCriteria();
        criteria.andUseridEqualTo(account);
        if(isDifference) {
            criteria.andAgentidEqualTo(agentId);
        }
        criteria.andStatusBetween(2,3);//  只展示支付成功、業務處理成功的数据
        criteria.andCardAfterEndtimeGreaterThan(new Date());
        example.setOrderByClause("CreateTime desc");
        return businessOrderUmbrellaTimecardService.selectByExample(example);
    }
    /**
     * 查询时长卡记录
     * @param account
     * @param page
     * @return
     */
    public List<BusinessOrderUmbrellaTimecard> queryTimecardList(Integer account,String machineCode,Integer page) throws Exception {
        LOGGER.info( "Start queryTimecardList" );
        Integer agentId = null ;
        if(StringUtils.isNotBlank(machineCode)) {//如果存在设备码，则使用设备码获取规则
            UmbrellaHardwareMachine machine = super.baseSelectUmbrellaHardwareMachineNoCache(machineCode);
            if (machine != null) {
                agentId = machine.getAgentId();
            }
        }
        if(agentId == null ){
            //查询用户账号
            WechatMpGzuser gzuser = wechatMpGzuserService.selectByPrimaryKey(account);
            gzuser.getUserAgentId();
        }

        if(agentId == null ){
            return new ArrayList<BusinessOrderUmbrellaTimecard>();
        }
        boolean isDifference = false;
        try{
            isDifference = "true".equals(upmsSystemParamService.querySystemParamValueByParam_key("BUSINESS_ORDER_TIMECARD_SETTLE_DIFF_AGENT"));
        }catch(Exception e){}

        int rows = 10;
        int tmpPage = StringUtil.getInt(page, 1);
        BusinessOrderUmbrellaTimecardExample example = new BusinessOrderUmbrellaTimecardExample();
        BusinessOrderUmbrellaTimecardExample.Criteria criteria = example.createCriteria();
        criteria.andUseridEqualTo(account);
        if(isDifference) {
            criteria.andAgentidEqualTo(agentId);
        }
        criteria.andStatusBetween(2,3);//  只展示支付成功、業務處理成功的数据
        example.setOrderByClause("CreateTime desc");
        Integer total = businessOrderUmbrellaTimecardService.countByExample(example);
        Integer offset = (tmpPage - 1) * rows;
        if(offset>total)return new ArrayList<BusinessOrderUmbrellaTimecard>();
        return businessOrderUmbrellaTimecardService.selectByExampleForOffsetPage(example, (tmpPage - 1) * rows, rows);
    }
    /**
     * 查询雨伞借还记录
     * @param account
     * @param page
     * @return
     */
    public List<BusinessOrderUmbrellaConsumption> queryConsumptionList(Integer account,Integer page) throws Exception {
        LOGGER.info( "Start queryConsumptionList" );
        int rows = 10;
        int tmpPage = StringUtil.getInt(page, 1);
        BusinessOrderUmbrellaConsumptionExample consumptionExample = new BusinessOrderUmbrellaConsumptionExample();
        consumptionExample.createCriteria().andUseridEqualTo(account);
        consumptionExample.setOrderByClause("endtime desc");
        Integer total = businessOrderUmbrellaConsumptionService.countByExample(consumptionExample);
        Integer offset = (tmpPage - 1) * rows;
        if(offset>total)return new ArrayList<BusinessOrderUmbrellaConsumption>();
        return businessOrderUmbrellaConsumptionService.selectByExampleForOffsetPage(consumptionExample, (tmpPage - 1) * rows, rows);
    }

    /**
     * 处理支付中心支付结果通知
     * @return
     */
    public String payBusinessNotify(HttpServletRequest request) {

        String resStr = "fail";
        LOGGER.info("====== 开始处理支付中心支付通知 ======");
        Map<String,Object> paramMap = request2ResponseMap(request, new String[]{
                "payorderid","mchid","mchorderno","channelid","amount","currency","status", "clientip",
                "device",  "subject", "channelorderno", "param1",
                "param2","paysucctime","backtype","sign"
        });
        LOGGER.info("支付中心通知请求参数,paramMap={}", paramMap);
        if (!verifyPayResponse(paramMap)) {
            String errorMessage = "verify request param failed.";
            LOGGER.warn(errorMessage);
            resStr = "fail";
            return resStr ;
        }
        String payOrderId = (String) paramMap.get("payorderid");
        String mchOrderNo = (String) paramMap.get("mchorderno");
        //增加prepayid保存，用于后续小程序发送模板消息
        String prepayid = "";
        Integer userId = null;
        try {
            int status = Integer.parseInt(paramMap.get("status").toString());
            //元
            BigDecimal amount = new BigDecimal(AmountUtil.convertCent2Dollar(paramMap.get("amount").toString()));
            //充值订单
            if(mchOrderNo.startsWith(ModuleConstant.PAY_ORDER_BIZ_SEQUENCE_NO_PREFIX.concat(ModuleConstant.UMBRELLA_RECHARGE_BIZ_SEQUENCE_NO_PREFIX))){
                //查询订单
                BusinessOrderUmbrellaRecharge recharge = super.baseSelectBusinessOrderUmbrellaRecharge(mchOrderNo);
                //已成功或者已经完成业务处理，直接返回成功
                if(recharge != null && (recharge.getStatus() == PayConstant.PAY_STATUS_SUCCESS || recharge.getStatus() == PayConstant.PAY_STATUS_COMPLETE)){
                    resStr = "success";
                    return resStr;
                }
                BusinessOrderUmbrellaRechargeExample rechargeExample = new BusinessOrderUmbrellaRechargeExample();
                BusinessOrderUmbrellaRechargeExample.Criteria  rechargeCriteria = rechargeExample.createCriteria();
                rechargeCriteria.andOrdernoEqualTo(mchOrderNo);
                rechargeCriteria.andStatusEqualTo(PayConstant.PAY_STATUS_INIT & 0xFF);
                //更新订单
                BusinessOrderUmbrellaRecharge updateRecharge = new BusinessOrderUmbrellaRecharge();
                updateRecharge.setStatus(status);
                if((PayConstant.PAY_STATUS_SUCCESS & 0xFF) == status) {
                    updateRecharge.setPaysucctime(DateUtil.getDate());
                    //获取pripayid
                    userId = recharge.getUserid();
                    prepayid = recharge.getPrepayid();
                }
                int ret = 0 ;
                // ret返回结果
                // 等于1表示处理成功,返回支付中心success
                // 其他值,返回支付中心fail,让稍后再通知
                 ret = businessOrderUmbrellaRechargeService.updateByExampleSelective(updateRecharge,rechargeExample);
                 if(ret==1) {
                     if((PayConstant.PAY_STATUS_SUCCESS & 0xFF) == status) {
                         //查询余额
                         WechatMpSystemAccount account = super.baseSelectWechatMpSystemAccont(recharge.getUserid());
                         //增加余额
                         WechatMpSystemAccount updateAccount = new WechatMpSystemAccount();
                         updateAccount.setAmount(account.getAmount().add(recharge.getAmount()));
                         WechatMpSystemAccountExample accountExample = new WechatMpSystemAccountExample();
                         WechatMpSystemAccountExample.Criteria accountCriteria = accountExample.createCriteria();
                         accountCriteria.andUserIdEqualTo(recharge.getUserid());
                         ret = wechatMpSystemAccountService.updateByExampleSelective(updateAccount, accountExample);
                         //更新订单为业务处理完成

                         BusinessOrderUmbrellaRecharge updateRecharge2 = new BusinessOrderUmbrellaRecharge();
                         updateRecharge2.setStatus(PayConstant.PAY_STATUS_COMPLETE & 0xFF);
                         BusinessOrderUmbrellaRechargeExample rechargeExample2 = new BusinessOrderUmbrellaRechargeExample();
                         BusinessOrderUmbrellaRechargeExample.Criteria  rechargeCriteria2 = rechargeExample2.createCriteria();
                         rechargeCriteria2.andOrdernoEqualTo(mchOrderNo);
                         rechargeCriteria2.andStatusEqualTo(PayConstant.PAY_STATUS_SUCCESS & 0xFF);
                         ret = businessOrderUmbrellaRechargeService.updateByExampleSelective(updateRecharge2, rechargeExample2);
                     }
                     resStr = "success";
                 } else{
                     resStr = "fail";
                 }

            //预付金订单
            }else if(mchOrderNo.startsWith(ModuleConstant.PAY_ORDER_BIZ_SEQUENCE_NO_PREFIX.concat(ModuleConstant.UMBRELLA_DEPOSIT_BIZ_SEQUENCE_NO_PREFIX))){
                //查询订单
                BusinessOrderUmbrellaDeposit deposit = super.baseSelectBusinessOrderUmbrellaDeposit(mchOrderNo);
                //已成功或者已经完成业务处理，直接返回成功
                if(deposit != null && (deposit.getStatus() == PayConstant.PAY_STATUS_SUCCESS || deposit.getStatus() == PayConstant.PAY_STATUS_COMPLETE)){
                    resStr = "success";
                    return resStr;
                }
                BusinessOrderUmbrellaDepositExample depositExample = new BusinessOrderUmbrellaDepositExample();
                BusinessOrderUmbrellaDepositExample.Criteria  depositCriteria = depositExample.createCriteria();
                depositCriteria.andOrdernoEqualTo(mchOrderNo);
                depositCriteria.andStatusEqualTo(PayConstant.PAY_STATUS_INIT & 0xFF);
                BusinessOrderUmbrellaDeposit updateDeposit = new BusinessOrderUmbrellaDeposit();
                updateDeposit.setStatus(status);
                if((PayConstant.PAY_STATUS_SUCCESS & 0xFF) == status) {
                    updateDeposit.setPaysucctime(DateUtil.getDate());
                    //获取pripayid
                    userId = updateDeposit.getUserid();
                    prepayid = updateDeposit.getPrepayid();
                }
                // 更新订单
                int ret = businessOrderUmbrellaDepositService.updateByExampleSelective(updateDeposit,depositExample);
                // ret返回结果
                // 等于1表示处理成功,返回支付中心success
                // 其他值,返回支付中心fail,让稍后再通知
                if(ret == 1) {
                    if((PayConstant.PAY_STATUS_SUCCESS & 0xFF) == status) {
                        //查询预付金
                        WechatMpSystemAccount account = super.baseSelectWechatMpSystemAccont(deposit.getUserid());
                        //增加预付金
                        WechatMpSystemAccountExample accountExample = new WechatMpSystemAccountExample();
                        WechatMpSystemAccountExample.Criteria accountCriteria = accountExample.createCriteria();
                        accountCriteria.andUserIdEqualTo(deposit.getUserid());
                        WechatMpSystemAccount updateAccount = new WechatMpSystemAccount();
                        updateAccount.setDeposit(account.getDeposit().add(deposit.getPayamount()));
                        ret = wechatMpSystemAccountService.updateByExampleSelective(updateAccount, accountExample);
                        //更新订单为业务处理完成
                        BusinessOrderUmbrellaDepositExample depositExample2 = new BusinessOrderUmbrellaDepositExample();
                        BusinessOrderUmbrellaDepositExample.Criteria  depositCriteria2 = depositExample2.createCriteria();
                        depositCriteria2.andOrdernoEqualTo(mchOrderNo);
                        depositCriteria2.andStatusEqualTo(PayConstant.PAY_STATUS_SUCCESS & 0xFF);
                        BusinessOrderUmbrellaDeposit updateDeposit2 = new BusinessOrderUmbrellaDeposit();
                        updateDeposit2.setStatus(PayConstant.PAY_STATUS_COMPLETE & 0xFF);
                        ret = businessOrderUmbrellaDepositService.updateByExampleSelective(updateDeposit2,depositExample2);
                    }
                    resStr = "success";
                }else {
                    resStr = "fail";
                }
            //时长卡订单
            }else if(mchOrderNo.startsWith(ModuleConstant.PAY_ORDER_BIZ_SEQUENCE_NO_PREFIX.concat(ModuleConstant.UMBRELLA_TIMECARD_BIZ_SEQUENCE_NO_PREFIX))){
                //查询订单
                BusinessOrderUmbrellaTimecard timecardOrder = super.baseSelectBusinessOrderUmbrellaTimecard(mchOrderNo);
                //已成功或者已经完成业务处理，直接返回成功
                if(timecardOrder != null && (timecardOrder.getStatus() == PayConstant.PAY_STATUS_SUCCESS || timecardOrder.getStatus() == PayConstant.PAY_STATUS_COMPLETE)){
                    resStr = "success";
                    return resStr;
                }
                Date nowDate = DateUtil.getDate();
                BusinessOrderUmbrellaTimecardExample timecardExample = new BusinessOrderUmbrellaTimecardExample();
                BusinessOrderUmbrellaTimecardExample.Criteria  timecardCriteria = timecardExample.createCriteria();
                timecardCriteria.andOrdernoEqualTo(mchOrderNo);
                timecardCriteria.andStatusEqualTo(PayConstant.PAY_STATUS_INIT & 0xFF);
                BusinessOrderUmbrellaTimecard updateTimecard = new BusinessOrderUmbrellaTimecard();
                updateTimecard.setStatus(status);
                if((PayConstant.PAY_STATUS_SUCCESS & 0xFF) == status) {
                    updateTimecard.setPaysucctime(nowDate);
                    //获取pripayid
                    userId = updateTimecard.getUserid();
                    prepayid = updateTimecard.getPrepayid();

                    //更新相关时间数据
                    try {
                        //根据用户和代理查询用户已购买的有效时长卡
                        BusinessOrderUmbrellaTimecard lastTimeCard = super.baseSelectLastBusinessOrderUmbrellaTimecardNoCache(timecardOrder.getUserid(), timecardOrder.getAgentid(), false);
                        BusinessOrderUmbrellaTimecard fisrtTimeCard = super.baseSelectFirstBusinessOrderUmbrellaTimecardNoCache(timecardOrder.getUserid(), timecardOrder.getAgentid(), false);
                        //已购买时长卡还没到期，则在到期时间基础上加购买时长
                        if (lastTimeCard != null && lastTimeCard.getCardAfterEndtime() != null && lastTimeCard.getCardAfterEndtime().after(nowDate)) {
                            updateTimecard.setCardPreEndtime(lastTimeCard.getCardAfterEndtime());
                            updateTimecard.setCardAfterBegintime(lastTimeCard.getCardAfterEndtime());
                            updateTimecard.setCardAfterEndtime(TimeCardUtil.getTimecardEndTime(lastTimeCard.getCardAfterEndtime(), timecardOrder.getCardtype()));
                        } else {
                            //首次购买或已到期，则在当前时间上加购买时长
                            if (lastTimeCard != null) {
                                updateTimecard.setCardPreEndtime(lastTimeCard.getCardAfterEndtime());
                            } else {
                                updateTimecard.setCardPreEndtime(nowDate);
                            }
                            updateTimecard.setCardAfterBegintime(nowDate);
                            updateTimecard.setCardAfterEndtime(TimeCardUtil.getTimecardEndTime(nowDate, timecardOrder.getCardtype()));
                        }
                        //首次使用时长卡时间
                        if (fisrtTimeCard != null) {
                            updateTimecard.setCardFirsttime(fisrtTimeCard.getCardFirsttime());
                        } else {
                            updateTimecard.setCardFirsttime(nowDate);
                        }
                    }catch (Exception e){}
                }
                // 更新订单
                int ret = businessOrderUmbrellaTimecardService.updateByExampleSelective(updateTimecard,timecardExample);
                // ret返回结果
                // 等于1表示处理成功,返回支付中心success
                // 其他值,返回支付中心fail,让稍后再通知
                if(ret == 1) {
                    if((PayConstant.PAY_STATUS_SUCCESS & 0xFF) == status) {
                        //更新订单为业务处理完成
                        BusinessOrderUmbrellaTimecardExample timecardExample2 = new BusinessOrderUmbrellaTimecardExample();
                        BusinessOrderUmbrellaTimecardExample.Criteria  timecardCriteria2 = timecardExample2.createCriteria();
                        timecardCriteria2.andOrdernoEqualTo(mchOrderNo);
                        timecardCriteria2.andStatusEqualTo(PayConstant.PAY_STATUS_SUCCESS & 0xFF);
                        BusinessOrderUmbrellaTimecard updateTimecard2 = new BusinessOrderUmbrellaTimecard();
                        updateTimecard2.setStatus(PayConstant.PAY_STATUS_COMPLETE & 0xFF);
                        ret = businessOrderUmbrellaTimecardService.updateByExampleSelective(updateTimecard2,timecardExample2);

                        //更新时长卡规则购买数量
                        UmbrellaRuleTimecard umbrellaRuleTimecard = baseSelectUmbrellaRuleTimecardNoCache(timecardOrder.getRuleid(), false);
                        UmbrellaRuleTimecardExample timecardExample3 = new UmbrellaRuleTimecardExample();
                        UmbrellaRuleTimecardExample.Criteria  timecardCriteria3 = timecardExample3.createCriteria();
                        timecardCriteria3.andIdEqualTo(timecardOrder.getRuleid());
                        UmbrellaRuleTimecard updateTimecard3 = new UmbrellaRuleTimecard();
                        updateTimecard3.setBuycount(umbrellaRuleTimecard.getBuycount()+1);
                        ret = umbrellaRuleTimecardService.updateByExampleSelective(updateTimecard3,timecardExample3);

                    }
                    resStr = "success";
                }else {
                    resStr = "fail";
                }
            }
        }catch (Exception e) {
            resStr = "fail";
            LOGGER.error("执行业务异常,payorderid=%s.mchorderno=%s", payOrderId, mchOrderNo,e);
        }finally {
            //增加prepayid保存，用于后续小程序发送模板消息
            if(userId != null && StringUtils.isNotEmpty(prepayid)){
                super.insertWechatMpWxappfromIdByUserId(userId,prepayid,1,3);
            }
        }
        LOGGER.info("响应支付中心支付通知结果:{},payorderid={},mchorderno={}", resStr, payOrderId, mchOrderNo);
        LOGGER.info("====== 支付中心通知支付处理完成 ======");
         return resStr;
    }

    /**
     * 处理支付中心退款结果通知
     * @return
     */
    public String refundBusinessNotify(HttpServletRequest request) {
        String resStr = "fail";
        LOGGER.info("====== 开始处理支付中心退款通知 ======");
        Map<String,Object> paramMap = request2ResponseMap(request, new String[]{
                "refundorderid","mchid","mchorderno","channelid","refundamount","currency","status","result","clientip",
                "device", "channelorderno", "param1",
                "param2","refundsucctime","backtype","sign"
        });
        LOGGER.info("支付中心通知请求参数,paramMap={}", paramMap);
        if (!verifyRefundResponse(paramMap)) {
            String errorMessage = "verify request param failed.";
            LOGGER.warn(errorMessage);
            resStr = "fail";
            return resStr ;
        }
        String refundOrderId = (String) paramMap.get("refundorderid");
        String mchOrderNo = (String) paramMap.get("mchorderno");
        try {
            int status = Integer.parseInt(paramMap.get("status").toString());
            //元
            //BigDecimal refundamount = new BigDecimal(AmountUtil.convertCent2Dollar(paramMap.get("refundamount").toString()));
            //查询订单
            BusinessOrderUmbrellaDeposit deposit = super.baseSelectBusinessOrderUmbrellaDeposit(mchOrderNo);
            //已成功或者已经完成业务处理，直接返回成功
            if(deposit != null && (deposit.getRefundstatus() == PayConstant.REFUND_STATUS_SUCCESS || deposit.getRefundstatus() == PayConstant.REFUND_STATUS_COMPLETE)){
                resStr = "success";
                return resStr;
            }
            BusinessOrderUmbrellaDepositExample depositExample = new BusinessOrderUmbrellaDepositExample();
            BusinessOrderUmbrellaDepositExample.Criteria  depositCriteria = depositExample.createCriteria();
            depositCriteria.andOrdernoEqualTo(mchOrderNo);
            depositCriteria.andRefundstatusEqualTo(PayConstant.REFUND_STATUS_INIT & 0xFF);
            //更新状态
            BusinessOrderUmbrellaDeposit updateDeposit = new BusinessOrderUmbrellaDeposit();
            updateDeposit.setRefundstatus(status & 0xFF);
            updateDeposit.setRefundorderid(refundOrderId);
            if((PayConstant.REFUND_STATUS_SUCCESS & 0xFF) == status) {
                updateDeposit.setRefundtime(DateUtil.getDate());
            }
            // 更新退款状态
            int ret = businessOrderUmbrellaDepositService.updateByExampleSelective(updateDeposit,depositExample);
            // ret返回结果
            // 等于1表示处理成功,返回支付中心success
            // 其他值,返回支付中心fail,让稍后再通知
            if(ret == 1) {
                if((PayConstant.REFUND_STATUS_SUCCESS & 0xFF) == status) {
                    //查询预付金
                    WechatMpSystemAccount account = super.baseSelectWechatMpSystemAccont(deposit.getUserid());
                    //减少预付金
                    WechatMpSystemAccount updateAccount = new WechatMpSystemAccount();
                    BigDecimal depositAmount = account.getDeposit().subtract(deposit.getRefundamount());
                    //为负数则特殊处理
                    if(depositAmount.compareTo(BigDecimal.ZERO) == -1){
                        depositAmount = BigDecimal.ZERO;
                    }
                    updateAccount.setDeposit(depositAmount);
                    WechatMpSystemAccountExample accountExample = new WechatMpSystemAccountExample();
                    WechatMpSystemAccountExample.Criteria accountCriteria = accountExample.createCriteria();
                    accountCriteria.andUserIdEqualTo(deposit.getUserid());
                    ret = wechatMpSystemAccountService.updateByExampleSelective(updateAccount, accountExample);
                    //更新退款订单为业务处理完成
                    BusinessOrderUmbrellaDepositExample depositExample2 = new BusinessOrderUmbrellaDepositExample();
                    BusinessOrderUmbrellaDepositExample.Criteria  depositCriteria2 = depositExample2.createCriteria();
                    depositCriteria2.andOrdernoEqualTo(mchOrderNo);
                    depositCriteria2.andRefundstatusEqualTo(PayConstant.REFUND_STATUS_SUCCESS & 0xFF);
                    BusinessOrderUmbrellaDeposit updateDeposit2 = new BusinessOrderUmbrellaDeposit();
                    updateDeposit2.setRefundstatus(PayConstant.REFUND_STATUS_COMPLETE & 0xFF);
                    ret = businessOrderUmbrellaDepositService.updateByExampleSelective(updateDeposit2,depositExample2);
                }
                resStr = "success";
            }else {
                resStr = "fail";
            }
        }catch (Exception e) {
            resStr = "fail";
            LOGGER.error("执行业务异常,refundorderid=%s.mchorderno=%s", refundOrderId, mchOrderNo,e);
        }
        LOGGER.info("响应支付中心退款通知结果:{},refundorderid={},mchorderno={}", resStr, refundOrderId, mchOrderNo);
        LOGGER.info("====== 支付中心通知退款处理完成 ======");
        return resStr;
    }
    private Map<String, Object> request2ResponseMap(HttpServletRequest request, String[] paramArray) {
        Map<String, Object> responseMap = new HashMap<>();
        for (int i = 0;i < paramArray.length; i++) {
            String key = paramArray[i];
            String v = request.getParameter(key);
            if (v != null) {
                responseMap.put(key, v);
            }
        }
        return responseMap;
    }
    private boolean verifyPayResponse(Map<String,Object> map) {
        String mchId = (String) map.get("mchid");
        String payOrderId = (String) map.get("payorderid");
        String amount = (String) map.get("amount");
        String sign = (String) map.get("sign");

        if (org.apache.commons.lang3.StringUtils.isEmpty(mchId)) {
            LOGGER.warn("Params error. mchid={}", mchId);
            return false;
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(payOrderId)) {
            LOGGER.warn("Params error. payorderid={}", payOrderId);
            return false;
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(amount) || !NumberUtils.isNumber(amount)) {
            LOGGER.warn("Params error. amount={}", amount);
            return false;
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(sign)) {
            LOGGER.warn("Params error. sign={}", sign);
            return false;
        }

        // 验证签名
        if (!verifySign(map)) {
            LOGGER.warn("verify params sign failed. payorderid={}", payOrderId);
            return false;
        }
        return true;
    }
    private boolean verifyRefundResponse(Map<String,Object> map) {
        String mchId = (String) map.get("mchid");
        String refundOrderId = (String) map.get("refundorderid");
        String sign = (String) map.get("sign");
        if (org.apache.commons.lang3.StringUtils.isEmpty(mchId)) {
            LOGGER.warn("Params error. mchid={}", mchId);
            return false;
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(refundOrderId)) {
            LOGGER.warn("Params error. refundorderid={}", refundOrderId);
            return false;
        }
        if (org.apache.commons.lang3.StringUtils.isEmpty(sign)) {
            LOGGER.warn("Params error. sign={}", sign);
            return false;
        }
        // 验证签名
        if (!verifySign(map)) {
            LOGGER.warn("verify params sign failed. refundorderid={}", refundOrderId);
            return false;
        }
        return true;
    }
    private boolean verifySign(Map<String, Object> map) {
        String mchId = (String) map.get("mchid");
        String tmpRepKey = "";
        PayMchInfo mchInfo = super.baseSelectPayMchInfoByMchId(mchId);
        if(mchInfo!=null){
            tmpRepKey = mchInfo.getReskey();
        }
        String localSign = DigestUtil.getSign(map, tmpRepKey, "sign");
        String sign = (String) map.get("sign");
        return localSign.equalsIgnoreCase(sign);
    }


    /**
     * 结算订单
     * @param orderNo
     * @param isNormal 是否正常结算
     * @param isCharge 是否计费
     * @param isLoss 是否雨伞损坏、超时结算
     * @return
     */
    public void completeBusinessOrderUmbrellaConsumption(String orderNo,boolean isNormal,boolean isCharge,boolean isLoss){
        BusinessOrderUmbrellaConsumption consumption = this.baseSelectBusinessOrderUmbrellaConsumptionByOrderNo(orderNo);
        if(consumption==null){return ;}

        //查询用户账号
        WechatMpSystemAccount wechatMpSystemAccount = baseSelectWechatMpSystemAccont(consumption.getUserid());

        boolean isDifference = false;
        try{
            isDifference = "true".equals(upmsSystemParamService.querySystemParamValueByParam_key("BUSINESS_ORDER_TIMECARD_SETTLE_DIFF_AGENT"));
        }catch(Exception e){}
        //用户购买的对应订单代理的时长卡
        BusinessOrderUmbrellaTimecard latestTimeCard =  baseSelectLastBusinessOrderUmbrellaTimecardNoCache(consumption.getUserid(),consumption.getAgentid(),isDifference);

        Date nowDate = DateUtil.getDate();

        Date endTime = consumption.getEndtime()==null?DateUtil.getDate():consumption.getEndtime();
        //时长卡用户
        boolean isCardUser = false;
        if(latestTimeCard!=null && latestTimeCard.getCardAfterEndtime()!=null && latestTimeCard.getCardAfterEndtime().after(nowDate)){
            isCardUser = true;
        }

        double cost = 0;//计时费用
        double payCost = 0;//实付费用
        int paymethod = PayConstant.PAY_METHOD_10;//默认余额支付
        if (isNormal) {
            //按租金模式计费
            UmbrellaRuleRent rent = this.baseSelectUmbrellaRuleRentNoCache(consumption.getRentRuleId(), false);
            if (rent == null) {
                return;
            }
            cost = MoneyUtil.getCostBetweenTime(consumption.getBegintime(), endTime, rent.getPrice().doubleValue(), rent.getChargelength(), rent.getChargetype(),
                    rent.getFreetimelength(), rent.getFreetimetype());
            //时长卡用户
            if(isCardUser){
                payCost = 0;
            }else{
                payCost = cost;
                //增加封顶金额计算租金
                if(cost>consumption.getLimitamount().doubleValue() && consumption.getLimitamount().doubleValue()>0){
                    payCost = consumption.getLimitamount().doubleValue();
                }
            }
        }else{
            if(isCharge && isLoss){
                //非正常结算并且计费报损雨伞
                if(isCardUser) {
                    cost = latestTimeCard.getPayamount().doubleValue();
                }else{
                    cost = wechatMpSystemAccount.getDeposit().doubleValue();
                }
                payCost = cost;
            }else if(isCharge && !isLoss){
                //按租金模式计费
                UmbrellaRuleRent rent = this.baseSelectUmbrellaRuleRentNoCache(consumption.getRentRuleId(), false);
                if (rent != null) {
                    cost = MoneyUtil.getCostBetweenTime(consumption.getBegintime(), endTime, rent.getPrice().doubleValue(), rent.getChargelength(), rent.getChargetype(),
                            rent.getFreetimelength(), rent.getFreetimetype());
                }
                //时长卡用户
                if(isCardUser){
                    payCost = 0;
                    paymethod = PayConstant.PAY_METHOD_13;
                }else {
                    payCost = cost;
                    //增加封顶金额计算租金
                    if(cost>consumption.getLimitamount().doubleValue() && consumption.getLimitamount().doubleValue()>0){
                        payCost = consumption.getLimitamount().doubleValue();
                    }
                }
            }else{
                cost = 0;
                payCost = 0;
            }
        }
        //a.compareTo(b) == -1 ,a小于b // a.compareTo(b) == 0 ,a等于b // a.compareTo(b) == 1 ,a大于b // a.compareTo(b) > -1 ,a大于等于 // a.compareTo(b) < 1 ,a小于等于b
        //更新订单
        BigDecimal costDecimal = new BigDecimal(cost);
        BigDecimal payCostDecimal = new BigDecimal(payCost);
        BusinessOrderUmbrellaConsumption updateConsumption = new BusinessOrderUmbrellaConsumption();
        updateConsumption.setEndtime(endTime);
        updateConsumption.setRentamount(costDecimal);//租金金额
        updateConsumption.setPayamount(payCostDecimal);//实付金额
        updateConsumption.setDiscountedamount(costDecimal.subtract(payCostDecimal));//折扣金额
        updateConsumption.setStatus(BusinessConstant.UM_CONSUMPTION_ORDER_STATUS_6);

        //报损并更新雨伞损失状态
        if(!isNormal && isLoss){
            updateUmbrellaHardwareUmbrellaStatus(consumption.getChipNumber(), UmbrellaConstant.UM_UMBRELLA_STATUS_6,null);
            //报损雨伞
            updateConsumption.setLostStatus(Constant.CONST_YES);
        }

        //处理用户账号数据
        WechatMpSystemAccount updateAccount = new WechatMpSystemAccount();
        updateAccount.setUserId(consumption.getUserid());
        //更新用户借伞数量
        if(!isNormal){
            int number = wechatMpSystemAccount.getUmbrellanumber() -1;
            if(number<0){number=0;}
            updateAccount.setUmbrellanumber(number);
        }
        //时长卡用户
        if(isCardUser){
            updateConsumption.setPaymethod(PayConstant.PAY_METHOD_13);
            updateConsumption.setDescription("时长卡支付");
        }else{
            // 预付金扣费
            BigDecimal zero = new BigDecimal(0);
            if (wechatMpSystemAccount.getAmount().compareTo(zero) <= 0) { // 充值余额 小于等于0, 直接扣取预付金
                BigDecimal yj = wechatMpSystemAccount.getDeposit().subtract(payCostDecimal);
                if (yj.compareTo(zero) >= 0) { // 预付金扣剩余
                    updateAccount.setDeposit(yj);
                    //预付金支付
                    updateConsumption.setPaymethod(PayConstant.PAY_METHOD_11);
                    updateConsumption.setDescription("预付金支付");
                } else {      // 预付金不够扣 扣取余额
                    updateAccount.setDeposit(zero);
                    updateAccount.setAmount(yj.add(updateAccount.getAmount()));
                    //混合支付
                    updateConsumption.setPaymethod(PayConstant.PAY_METHOD_14);
                    updateConsumption.setDescription("余额+预付金支付");
                }
            } else { // 余额大于0 先扣除余额
                BigDecimal ye = wechatMpSystemAccount.getAmount().subtract(payCostDecimal);
                if (ye.compareTo(zero) >= 0) { // 余额足扣
                    updateAccount.setAmount(ye);
                    updateAccount.setDeposit(wechatMpSystemAccount.getDeposit());
                    //余额支付
                    updateConsumption.setPaymethod(PayConstant.PAY_METHOD_10);
                    updateConsumption.setDescription("余额支付");
                } else { // 余额不足扣
                    BigDecimal yj = wechatMpSystemAccount.getDeposit().add(ye);
                    if (yj.compareTo(zero) >= 0) { // 预付金扣剩余
                        updateAccount.setDeposit(yj);
                    } else {      // 预付金不够扣
                        updateAccount.setDeposit(zero);
                        updateAccount.setAmount(yj.add(updateAccount.getAmount()));
                    }
                    //混合支付
                    updateConsumption.setPaymethod(PayConstant.PAY_METHOD_14);
                    updateConsumption.setDescription("余额+预付金支付");
                }
            }
        }
        //更新用户账号
        WechatMpSystemAccountExample accountExample = new WechatMpSystemAccountExample();
        accountExample.createCriteria().andUserIdEqualTo(consumption.getUserid());
        wechatMpSystemAccountService.updateByExampleSelective(updateAccount,accountExample);

        //更新订单
        BusinessOrderUmbrellaConsumptionExample consumptionExample = new BusinessOrderUmbrellaConsumptionExample();
        BusinessOrderUmbrellaConsumptionExample.Criteria consumptionCriteria = consumptionExample.createCriteria();
        consumptionCriteria.andOrdernoEqualTo(orderNo);
        this.updateBusinessOrderUmbrellaConsumption(updateConsumption,consumptionExample);

        //发送还伞成功服务提醒(微信)
        wxTemplateService.miniAppTemplatePush(orderNo,2);

        //时长卡用户
        if(isCardUser){
            //只计费报失场景
            if(isCharge && isLoss){
                //更新时长卡为失效
                BusinessOrderUmbrellaTimecard updateTimecard = new BusinessOrderUmbrellaTimecard();
                updateTimecard.setStatus(PayConstant.PAY_STATUS_EXPIRED & 0xFF);
                updateTimecard.setDescription("损失雨伞，已被失效。");
                BusinessOrderUmbrellaTimecardExample timecardExample = new BusinessOrderUmbrellaTimecardExample();
                BusinessOrderUmbrellaTimecardExample.Criteria  timecardCriteria = timecardExample.createCriteria();
                timecardCriteria.andOrdernoEqualTo(latestTimeCard.getOrderno());
                businessOrderUmbrellaTimecardService.updateByExampleSelective(updateTimecard,timecardExample);
            }
        }else {
            //查询用户账号
            WechatMpSystemAccount newSystemAccount = baseSelectWechatMpSystemAccont(consumption.getUserid());
            //预付金大于0才调用退款，否则直接更新预付金订单为已完成
            if (newSystemAccount.getDeposit() != null && newSystemAccount.getDeposit().doubleValue() > 0) {
                //退还预付金
                prepareReturnDeposit(consumption.getUserid(), "127.0.0.1", false);
            } else {
                BusinessOrderUmbrellaDepositExample depositExample = new BusinessOrderUmbrellaDepositExample();
                BusinessOrderUmbrellaDepositExample.Criteria depositCriteria = depositExample.createCriteria();
                depositCriteria.andUseridEqualTo(consumption.getUserid());
                //业务处理完成
                depositCriteria.andStatusEqualTo(3);
                //未退款（状态为空）
                depositCriteria.andRefundstatusIsNull();
                BusinessOrderUmbrellaDeposit businessOrderUmbrellaDeposit = businessOrderUmbrellaDepositService.selectFirstByExample(depositExample);
                if (businessOrderUmbrellaDeposit != null) {
                    /**
                     * 更新预付金订单为业务处理完成
                     */
                    BusinessOrderUmbrellaDepositExample depositExample2 = new BusinessOrderUmbrellaDepositExample();
                    BusinessOrderUmbrellaDepositExample.Criteria depositCriteria2 = depositExample2.createCriteria();
                    depositCriteria2.andOrdernoEqualTo(businessOrderUmbrellaDeposit.getOrderno());
                    BusinessOrderUmbrellaDeposit updateDeposit2 = new BusinessOrderUmbrellaDeposit();
                    updateDeposit2.setRefundstatus(PayConstant.REFUND_STATUS_COMPLETE & 0xFF);
                    updateDeposit2.setRefundtime(DateUtil.getDate());
                    businessOrderUmbrellaDepositService.updateByExampleSelective(updateDeposit2, depositExample2);
                }
            }
        }

    }

    /**
     * 免单
     * @param orderNo
     * @return
     */
    public void freeBusinessOrderUmbrellaConsumption(String orderNo){
        BusinessOrderUmbrellaConsumption consumption = this.baseSelectBusinessOrderUmbrellaConsumptionByOrderNo(orderNo);
        if(consumption==null){return ;}
        //查询用户账号
        WechatMpSystemAccount wechatMpSystemAccount = baseSelectWechatMpSystemAccont(consumption.getUserid());

        //更新订单
        BusinessOrderUmbrellaConsumption updateConsumption = new BusinessOrderUmbrellaConsumption();
        updateConsumption.setPayamount(new BigDecimal(0));//实付金额变为0
        updateConsumption.setDiscountedamount(consumption.getRentamount());//折扣金额变为租金金额

        BusinessOrderUmbrellaConsumptionExample consumptionExample = new BusinessOrderUmbrellaConsumptionExample();
        BusinessOrderUmbrellaConsumptionExample.Criteria consumptionCriteria = consumptionExample.createCriteria();
        consumptionCriteria.andOrdernoEqualTo(orderNo);
        this.updateBusinessOrderUmbrellaConsumption(updateConsumption,consumptionExample);

        WechatMpSystemAccount updateAccount = new WechatMpSystemAccount();
        //余额需返还原先订单扣除的实付余额
        updateAccount.setAmount(wechatMpSystemAccount.getAmount().add(consumption.getPayamount()));

        WechatMpSystemAccountExample accountExample = new WechatMpSystemAccountExample();
        accountExample.createCriteria().andUserIdEqualTo(consumption.getUserid());
        wechatMpSystemAccountService.updateByExampleSelective(updateAccount,accountExample);

    }
}
